package com.common.www.controller.sale;

import com.alibaba.fastjson.JSON;
import com.common.www.aop.resolver.CurrentUser;
import org.springframework.boot.base.jpa.domain.PageableRequest;
import org.springframework.boot.base.jpa.service.IBaseService;
import com.common.www.bean.entity.Result;
import com.common.www.bean.entity.Sort;
import com.common.www.bean.entity.auth.AuthUser;
import com.common.www.bean.entity.recycle.RecycleBill;
import com.common.www.bean.entity.recycle.RecycleBillImgItem;
import com.common.www.bean.entity.recycle.RecycleBillTypeItem;
import com.common.www.bean.entity.recycle.RecycleType;
import com.common.www.bean.entity.sale.*;
import com.common.www.bean.vo.UserVo;
import com.common.www.data.NetCode;
import com.common.www.service.auth.UserService;
import com.common.www.service.recycle.RecycleBillImgItemService;
import com.common.www.service.recycle.RecycleBillService;
import com.common.www.service.recycle.RecycleBillTypeItemService;
import com.common.www.service.recycle.RecycleTypeService;
import com.common.www.service.sale.*;
import com.common.www.utils.ParamsUtils;
import com.common.www.utils.R;
import com.common.www.utils.SortUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@RestController
@CrossOrigin()
@Transactional
@RequestMapping(value = {"api/sale"})
@Api(tags = "API 回收品类管理接口")
public class SaleController {
    @Autowired
    private RecycleTypeService recycleTypeService;
    @Autowired
    private RecycleBillService recycleBillService;
    @Autowired
    private RecycleBillTypeItemService recycleBillTypeItemService;
    @Autowired
    private RecycleBillImgItemService recycleBillImgItemService;

    @Autowired
    private SaleBillImgItemService saleBillImgItemService;
    @Autowired
    private SaleBillTypeItemService saleBillTypeItemService;
    @Autowired
    private SaleBillService saleBillService;
    @Autowired
    private SaleFactoryService saleFactoryService;
    @Autowired
    private SaleFactoryPriceService saleFactoryPriceService;
    @Autowired
    private UserService userService;

    protected IBaseService getService() {
        return recycleTypeService;
    }


    @ApiOperation("手机端查询品类列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "json", value = "String", defaultValue = ""),
    })
    @RequestMapping(value = "/getFactoryPriceList", method = RequestMethod.POST)
    public Result getFactoryPriceList(String factoryId, Integer page, Integer size) {
        if (ParamsUtils.isInputEmpty()) {
            return R.fail(NetCode.CODE_INPUT_OMIT);
        }
        if (page == null) {
            page = 1;
        }
        if (size == null) {
            size = 20;
        }
        HashMap hashMap = new HashMap();
        hashMap.put("flag", 1);
        if (StringUtils.isNotEmpty(factoryId)) {
            hashMap.put("saleFactory.id", factoryId);
        }
        PageableRequest pageableRequest = new PageableRequest();
        pageableRequest.setPage(page - 1);
        pageableRequest.setSize(size);
        pageableRequest.setSort(SortUtils.addSort(new Sort("createTime", "ASC")));
        List<SaleFactoryPrice> factoryPriceList = saleFactoryPriceService.getList(hashMap, pageableRequest);
        return R.ok(factoryPriceList);
    }

    @ApiOperation("手机端查询卖货单信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "json", value = "String", defaultValue = ""),
    })
    @RequestMapping(value = "/querySaleDataList", method = RequestMethod.GET)
    public Result queryBillDataList(String saleBillId, Integer status, Integer page, Integer size, @CurrentUser UserVo userVo) {
        if (ParamsUtils.isInputEmpty()) {
            return R.fail(NetCode.CODE_INPUT_OMIT);
        }
        if (page == null) {
            page = 1;
        }
        if (size == null) {
            size = 20;
        }

        HashMap hashMap = new HashMap();
        if (StringUtils.isNotEmpty(saleBillId)) {
            hashMap.put("id", saleBillId);
        }
        if (status != null) {
            //根据条件需要判断后添加值
            if (status == 0){
            }else if (status == 1){
                hashMap.put("payType_lt", 10);
                hashMap.put("periodStatus_lt", 100);
            }else if (status == 2){
                HashMap temp1HashMap = new HashMap();
                temp1HashMap.put("payType", 10);
                List<SaleBill> item1List = saleBillService.getList(temp1HashMap, null);
                Long[] ids1 = new Long[item1List.size()];
                for (int i = 0; i < item1List.size(); i++) {
                    ids1[i] = item1List.get(i).getId();
                }

                HashMap temp2HashMap = new HashMap();
                Integer[] commonValues = {1, 2, 3};
                temp2HashMap.put("payType_in", commonValues);
                temp2HashMap.put("periodStatus_ge", 100);
                List<SaleBill> item2List = saleBillService.getList(temp2HashMap, null);
                Long[] ids2 = new Long[item2List.size()];
                Long[] ids = new Long[item1List.size()+item2List.size()];
                for (int i = 0; i < item2List.size(); i++) {
                    ids2[i] = item2List.get(i).getId();
                }

                System.arraycopy(ids1, 0, ids, 0, ids1.length);
                System.arraycopy(ids2, 0, ids, ids1.length, ids2.length);
                if (ids.length > 0){
                    hashMap.put("id_in", ids);
                }
            }
        }
        PageableRequest pageableRequest = new PageableRequest();
        pageableRequest.setPage(page - 1);
        pageableRequest.setSize(size);
        pageableRequest.setSort(SortUtils.addSort(new Sort("createTime", "desc")));
        List<SaleBill> itemList = saleBillService.getList(hashMap, pageableRequest);
        return R.ok(itemList);
    }


    @ApiOperation("手机端查询回收工厂信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "json", value = "String", defaultValue = ""),
    })
    @RequestMapping(value = "/queryFactoryList", method = RequestMethod.GET)
    public Result queryFactoryList(Integer page, Integer size, @CurrentUser UserVo userVo) {
        if (ParamsUtils.isInputEmpty()) {
            return R.fail(NetCode.CODE_INPUT_OMIT);
        }
        if (page == null) {
            page = 1;
        }
        if (size == null) {
            size = 20;
        }

        HashMap hashMap = new HashMap();
        hashMap.put("code",userVo.getCode());
        PageableRequest pageableRequest = new PageableRequest();
        pageableRequest.setPage(page - 1);
        pageableRequest.setSize(size);
        pageableRequest.setSort(SortUtils.addSort(new Sort("createTime", "desc")));
        List<SaleFactory> itemList =saleFactoryService.getList(hashMap, pageableRequest);
        return R.ok(itemList);
    }


    @ApiOperation("合并已完成回收单，保存卖给工厂时的相关信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "json", value = "String", defaultValue = ""),
    })
    @RequestMapping(value = "/saveByJsonMaiChuComplete", method = RequestMethod.POST)
    public Result saveByJsonHuiShouComplete(String json, String recycleBillJson, String saleBillTypeItemListJson, String imgItemJson,@CurrentUser UserVo userVo) throws IOException {
        List<String> imgItemList = null;
        List<SaleBillTypeItem> typeItemList = null;
        List<RecycleBill> recycleBillList = null;
        ObjectMapper mapper = new ObjectMapper();

        SaleBill entity = JSON.parseObject(json, SaleBill.class);
        entity.setFlag(1);
        AuthUser createUser = userService.findOne(userVo.getId());
        entity.setCreateUser(createUser);
        if (entity.getId() == null) {//只有创建的时候才同步创建楼栋
        } else {
        }
        SaleBill item = saleBillService.saveAndFlush(entity);

        if (StringUtils.isNotEmpty(recycleBillJson)) {
            recycleBillList = JSON.parseArray(recycleBillJson, RecycleBill.class);
            for (RecycleBill recycleBill : recycleBillList){
                if (recycleBill.getId() != null){
                    recycleBill.setSaleBill(item);
                    recycleBill.setStatus(11);
                    recycleBill.setFlag(1);
                    RecycleBill tempRecycleBill = recycleBillService.save(recycleBill);
                    if (recycleBill.getTypeList().size() > 0){
                        for (RecycleBillTypeItem typeItem : recycleBill.getTypeList()){
                            typeItem.setBill(tempRecycleBill);
                            recycleBillTypeItemService.save(typeItem);
                        }
                    }
                    if (recycleBill.getImgItemList().size() > 0){
                        for (RecycleBillImgItem imgItem : recycleBill.getImgItemList()){
                            imgItem.setBill(tempRecycleBill);
                            recycleBillImgItemService.save(imgItem);
                        }
                    }
                }
            }
        }
        if (StringUtils.isNotEmpty(saleBillTypeItemListJson)) {
            typeItemList = JSON.parseArray(saleBillTypeItemListJson, SaleBillTypeItem.class);
            for (SaleBillTypeItem typeItem : typeItemList){
                if (typeItem.getId() == null){
                    typeItem.setSaleBill(item);
                    typeItem.setFlag(1);
                    saleBillTypeItemService.save(typeItem);
                }
            }
        }
        if (StringUtils.isNotEmpty(imgItemJson)) {
            imgItemList = mapper.readValue(imgItemJson, List.class);
            for (int i = 0; i < imgItemList.size(); i++) {
                SaleBillImgItem imgItem = new SaleBillImgItem();
                imgItem.setBill(item);
                imgItem.setName(imgItemList.get(i));
                imgItem.setFlag(1);
                saleBillImgItemService.save(imgItem);
            }
        }
        return R.ok(item);
    }



    @ApiOperation("卖给工厂时计算价格和重量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "json", value = "String", defaultValue = ""),
    })
    @RequestMapping(value = "/calculate-sale", method = RequestMethod.POST)
    public Result calculateSale(String saleBillTypeItemListJson) {
        List<SaleBillTypeItem> typeItemList = null;
        BigDecimal tempPriceActual = BigDecimal.ZERO;
        BigDecimal tempWeightActual = BigDecimal.ZERO;
        if (StringUtils.isNotEmpty(saleBillTypeItemListJson)) {
            typeItemList = JSON.parseArray(saleBillTypeItemListJson, SaleBillTypeItem.class);
            for (SaleBillTypeItem typeItem : typeItemList) {
                BigDecimal itemPrice = typeItem.getPriceActual();
                BigDecimal itemWeight = typeItem.getWeightActual();
                if (itemPrice == null) {
                    itemPrice = BigDecimal.ZERO;
                }
                if (itemWeight == null) {
                    itemWeight = BigDecimal.ZERO;
                }
                tempPriceActual = tempPriceActual.add(itemPrice.multiply(itemWeight));

                if (typeItem.getUnitType() == 1) {
                    // 如果价格单位是“元/吨”，将重量转换为克
                    itemWeight = itemWeight.multiply(new BigDecimal(1000));
                }
                tempWeightActual = tempWeightActual.add(itemWeight);
            }
        }
        // 设置价格和重量，保留4位小数
        BigDecimal maiChuPriceActual = tempPriceActual.setScale(4, RoundingMode.HALF_UP);
        BigDecimal maiChuWeightActual = tempWeightActual.setScale(4, RoundingMode.HALF_UP);

        HashMap hashMap = new HashMap();
        hashMap.put("maiChuPriceActual",maiChuPriceActual);
        hashMap.put("maiChuWeightActual",maiChuWeightActual);

        return R.ok(hashMap);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "json", value = "String", defaultValue = ""),
    })
    @RequestMapping(value = "/saveByJson-type", method = RequestMethod.POST)
    public Result saveByJson(String json) {
        RecycleType entity = JSON.parseObject(json, RecycleType.class);

        //子类不取传过来的值，只替换父类
        List<RecycleType> children = new ArrayList<>();
        if (entity.getId() != null) {
            RecycleType type1 = recycleTypeService.findOne(entity.getId());
//            entity.setFlag(type1.getFlag());
            entity.setCreateTime(type1.getCreateTime());
            children = type1.getChildren();

            if (children != null) {
                for (RecycleType type : children) {//修改的父类不能指向自己的子类避免进入死循环
                    if (entity.getParent() != null && entity.getParent().getId() != null
                            && type.getId() != null && entity.getParent().getId().equals(type.getId())) {
                        return null;
                    }
                }

            }
        } else {
            children = entity.getChildren();
            entity.setFlag(1);
            entity.setSort(9999);
            entity.setCreateTime(new Date());
            if (children != null)
                for (RecycleType type :
                        children) {//修改的父类不能指向自己的子类避免进入死循环
                    if (entity.getParent() != null && entity.getParent().getId() != null
                            && type.getId() != null && entity.getParent().getId().equals(type.getId())) {
                        return null;
                    }
                }
        }
        entity.setChildren(children);
        entity = recycleTypeService.save(entity);
        if (entity.getParent() != null && entity.getParent().getId() != null) {
            entity.setParent(recycleTypeService.findOne(entity.getParent().getId()));
        } else {
            entity.setParent(null);
        }
        //存储完后分析一次所有受影响的节点路劲再重新存储一次
        entity.setNodePath(recycleTypeService.getNodePath(entity, ""));
        recycleTypeService.sortType(entity);
        recycleTypeService.setChildNodePath(entity.getChildren());
        recycleTypeService.sortChildNodePath(entity.getChildren());
        entity.setLevel(recycleTypeService.getTypeLevel(entity));
        entity = recycleTypeService.save(entity);

        return R.ok(entity);
    }

    @ApiOperation("批量删除启用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "String", defaultValue = ""),
            @ApiImplicitParam(name = "operate", value = "1.删除 2.启用", defaultValue = ""),
    })
    @RequestMapping(value = "/batchDelete", method = RequestMethod.POST)
    public Result batchDelete(Long[] ids, Integer operate) {
        if (ParamsUtils.isInputEmpty(ids, operate)) {
            return R.returnCode(NetCode.CODE_INPUT_OMIT);
        }
        for (int i = 0; i < ids.length; i++) {
            RecycleType authUser = recycleTypeService.findOne(ids[i]);
            if (authUser != null) {
                if (operate == 1) {
                    authUser.setFlag(0);
                } else if (operate == 2) {
                    authUser.setFlag(1);
                }
                recycleTypeService.save(authUser);
            }
        }
        return R.ok();
    }


    @ApiOperation(value = "逻辑删除", notes = "参数为JSON数据对象")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "long", paramType = "query"),
    })
    @RequestMapping(value = "/deleteByLogic", method = RequestMethod.POST)
    public Result deleteByLogic(Long id) {
        recycleTypeService.deleteById(id);
        return R.ok();
    }

    @ApiOperation(value = "逻辑删除批量", notes = "参数为JSON数据对象")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "8,28", dataType = "long", paramType = "query"),
    })
    @RequestMapping(value = "/deletesByLogic", method = RequestMethod.POST)
    public Result deletesByLogic(Long[] ids) {
        recycleTypeService.deleteByIds(ids);
        return R.ok();
    }


    @ApiOperation("批量更新顺序")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "originId", value = "原id"),
            @ApiImplicitParam(name = "relId", value = "变动后相对变化的id"),
            @ApiImplicitParam(name = "type", value = "变化 类型 before  after  inner"),
    })
    @RequestMapping(value = "/updateSort", method = RequestMethod.POST)
    public Result updateSort(Long originId, Long relId, String type) {
        if (ParamsUtils.isInputEmpty(originId, relId, type)) {
            return R.returnCode(NetCode.CODE_INPUT_OMIT);
        }
        RecycleType originType = recycleTypeService.getById(originId);
        RecycleType relType = recycleTypeService.getById(relId);

        if (originType == null || relType == null) {
            return R.fail("操作失败");
        }
        if ("before".equals(type) || "after".equals(type)) {
            originType.setLevel(relType.getLevel());
            originType.setParent(relType.getParent());
//            //设置排序位置
            originType.setSort(relType.getSort());
            //查询同等级下相同类型的分类列表进行一次排序
            HashMap hashMap = new HashMap();
            hashMap.put("level", relType.getLevel());
            if (relType.getParent() != null)
                hashMap.put("parent.id", relType.getParent().getId());

            PageableRequest pageableRequest = new PageableRequest();
            pageableRequest.setSort(SortUtils.addSort(new Sort("sort", "asc")));
            List<RecycleType> list = recycleTypeService.getList(hashMap, pageableRequest);

            //先移除
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getId() == originType.getId()) {
                    list.remove(i--);
                }
            }

            int relIndex = 0;
            for (int i = 0; i < list.size(); i++) {
//                if (relType.getSort() == list.get(i).getSort()) {
//                    list.get(i).setSort(i);
//                }
                if (relType.getId() == list.get(i).getId()) {
                    relIndex = i;
                }
            }

            if ("before".equals(type)) {
                list.add(relIndex, originType);
            } else if ("after".equals(type)) {
                list.add(relIndex + 1, originType);
            }

            for (int i = 0; i < list.size(); i++) {
                list.get(i).setSort(i);
            }

            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i).getName() + "   " + list.get(i).getSort());
            }
            recycleTypeService.save(list);
            recycleTypeService.save(originType);
        } else if ("inner".equals(type)) {
            originType.setLevel(relType.getLevel() + 1);
            originType.setParent(relType);
//            //设置排序位置
            originType.setSort(relType.getSort());
            //查询同等级下相同类型的分类列表进行一次排序
            HashMap hashMap = new HashMap();
            hashMap.put("level", relType.getLevel() + 1);
            if (relType.getParent() != null)
                hashMap.put("parent.id", relType.getId());

            PageableRequest pageableRequest = new PageableRequest();
            pageableRequest.setSort(SortUtils.addSort(new Sort("sort", "asc")));
            List<RecycleType> list = recycleTypeService.getList(hashMap, pageableRequest);

            //先移除
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getId() == originType.getId()) {
                    list.remove(i--);
                }
            }

            list.add(originType);

            for (int i = 0; i < list.size(); i++) {
                list.get(i).setSort(i);
            }

            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i).getName() + "   " + list.get(i).getSort());
            }
            recycleTypeService.save(list);
            recycleTypeService.save(originType);
        }


        RecycleType entity = originType.getParent();
        if (entity != null) {//1级分类无需处理子分类的节点数据
            //存储完后分析一次所有受影响的节点路劲再重新存储一次
            entity.setNodePath(recycleTypeService.getNodePath(entity, ""));
            recycleTypeService.sortType(entity);
            recycleTypeService.setChildNodePath(entity.getChildren());
            recycleTypeService.sortChildNodePath(entity.getChildren());
            entity.setLevel(recycleTypeService.getTypeLevel(entity));
        }

        return R.ok();
    }

}

